package com.zf.bm.common.core.sys.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zf.bm.common.core.config.ConfigUtils;
import com.zf.bm.common.core.shiro.utils.ShiroUtils;
import com.zf.bm.common.core.sys.entity.Menu;
import com.zf.bm.common.core.sys.entity.Role;
import com.zf.bm.common.core.sys.entity.User;
import com.zf.bm.common.utils.Base64Util;
import com.zf.bm.common.utils.CacheUtils;
import com.zf.bm.common.utils.UserUtils;
import com.zf.bm.common.utils.ValidatorUtil;
import com.zf.bm.modules.system.service.MonitorAuditLogService;
import com.zf.bm.modules.system.utils.SystemUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static com.zf.bm.common.constant.Constant.CenterAuditType.ENUM_USER_OPT;
import static com.zf.bm.common.utils.DataScopeFilter.dataScopeFilter;


/**
 * 系统管理，安全相关实体的管理类,包括用户、角色、菜单.
 */
@Slf4j
@Service
@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
public class SystemService {


    @Autowired
    private UserService userService;
    @Autowired
    private RoleService roleService;
    @Autowired
    private MenuService menuService;
    @Autowired
    private MonitorAuditLogService logService;


    /**
     * 获取用户
     *
     * @param id
     * @return
     */
    public User getUser(Long id) {
        return UserUtils.get(id);
    }

    /**
     * 根据登录名获取用户
     *
     * @param loginName
     * @return
     */
    public User getUserByLoginName(String loginName) {
        return UserUtils.getByLoginName(loginName);
    }

    public IPage<User> findUser(Page<User> page, User user) {
        // 生成数据权限过滤条件（dsf为dataScopeFilter的简写，在xml中使用 ${sqlMap.dsf}调用权限SQL）
        user.getSqlMap().put("dsf", dataScopeFilter());
        QueryWrapper<User> queryWrapper = Wrappers.query(user);
        // 执行分页查询
        return userService.page(page, queryWrapper);
    }


    @Transactional(readOnly = false)
    public void saveUser(User user) {
        if (Objects.isNull(user.getId())) {
            if (Objects.isNull(user.getPwdPeriod())) {
                user.setPwdPeriod(ConfigUtils.getInt("sys.def.pwdperiod"));
            }
            user.setUpdateTime(new Date());
            userService.save(user);
            SystemUtils.saveSystemLog("用户", "添加", 3, "用户" + user.getLoginName() + "添加成功");
            // 保存用户日志
            String operateDesc = "添加用户"+user.getLoginName();
            logService.saveMonitorAuditLog("添加用户", operateDesc, ENUM_USER_OPT.getMsg());
        } else {
           User oldUser = userService.getById(user.getId());
           if(!oldUser.getLoginFlag().equals(user.getLoginFlag()) && "1".equals(user.getLoginFlag())){
               userService.update(Wrappers.lambdaUpdate(user)
                        .set(User::getFrozenDate, null)
                        .eq(User::getId, user.getId())
                );
            CacheUtils.cleanPasswdRetryCount(user.getLoginName());
           }
            if (ValidatorUtil.isNotEmptyObj(user.getPassword())) {
                user.setUpdateTime(new Date());
            }
            // 更新用户数据
            userService.updateById(user);
            SystemUtils.saveSystemLog("用户", "修改", 3, "用户" + user.getLoginName() + "修改成功");
        }
        // 更新用户与角色关联
        if (user.getRoleList() != null && user.getRoleList().size() > 0 && !user.isAdmin()) {
            userService.deleteUserRole(user);
            userService.insertUserRole(user);
        }
        // 清除用户缓存
        UserUtils.clearCache(user);
    }

    @Transactional(readOnly = false)
    public void deleteUser(User user) {
        userService.removeById(user);
        UserUtils.clearCache(user);
    }


    @Transactional(readOnly = false)
    public void updatePasswordById(Long id, String loginName, String newPassword, Integer modifyPwd, String userName) {

        try {
            User user1 = new User();
            user1.setSm3(null);
            LambdaUpdateWrapper updateWrapper = Wrappers.lambdaUpdate(user1)
                    .set(User::getPassword, ShiroUtils.entryptPassword(newPassword))
                    .set(User::getModifyPwd, modifyPwd)
                    //添加 2022 0311 zj
                    .set(User::getKeyPassword, Base64Util.encryption(newPassword))
                    .set(User::getName, userName)
                    .set(User::getLoginName, userName)
                    .set(User::getUpdateTime,new Date())
                    //添加 2021 0520 zj
                    .eq(User::getId, id);
            userService.update(updateWrapper);
            // 清除用户缓存
            User user = new User(id);
            user.setLoginName(loginName);
            UserUtils.clearCache(user);
        } catch (Exception e) {
            log.error("pwd解码失败 exception {}", e);
        }
    }

    public Role getRole(Long id) {
        return roleService.getById(id);
    }

    public Role getRoleByName(String name) {
        Role r = new Role();
        r.setName(name);
        return roleService.getByName(r);
    }


    public List<Role> findAllRole() {
        return UserUtils.getRoleList();
    }

    @Transactional(readOnly = false)
    public void saveRole(Role role) {
        if (Objects.isNull(role.getId())) {
            roleService.save(role);
        } else {
            roleService.updateById(role);
        }
        // 更新角色与菜单关联
        roleService.deleteRoleMenu(role.getId());
        if (role.getMenuList().size() > 0) {
            role.setEnname(role.getName());
            roleService.insertRoleMenu(role);
        }
        // 清除用户角色缓存
        UserUtils.removeCache(UserUtils.CACHE_ROLE_LIST);
    }

    @Transactional(readOnly = false)
    public void deleteRole(Role role) {
        roleService.removeById(role.getId());
        // 清除用户角色缓存
        UserUtils.removeCache(UserUtils.CACHE_ROLE_LIST);
    }


    // -- Menu Service --//

    public Menu getMenu(Long id) {
        return menuService.getById(id);
    }

    public List<Map<String,Integer>> queryByRoleId(Long id) {
        return menuService.queryByRoleId(id);
    }


    @Transactional(readOnly = false)
    public void saveMenu(Menu menu) {

        // 获取父节点实体
        menu.setParent(this.getMenu(menu.getParent().getId()));
        // 获取修改前的parentIds，用于更新子节点的parentIds
        String oldParentIds = menu.getParentIds();
        // 设置新的父节点串
        menu.setParentIds(menu.getParent().getParentIds() + menu.getParent().getId() + ",");
        // 保存或更新实体
        if (Objects.isNull(menu.getId())) {
            menuService.save(menu);
        } else {
            menuService.updateById(menu);
        }

        // 更新子节点 parentIds
        Menu m = new Menu();
        m.setParentIds("%," + menu.getId() + ",%");
        List<Menu> list = menuService.findByParentIdsLike(m);
        for (Menu e : list) {
            e.setParentIds(e.getParentIds().replace(oldParentIds, menu.getParentIds()));
            menuService.updateParentIds(e);
        }
        // 清除用户菜单缓存
        UserUtils.removeCache(UserUtils.CACHE_MENU_LIST);
        UserUtils.removeCache(UserUtils.CACHE_PERMISSION_LIST);
    }

    @Transactional(readOnly = false)
    public void updateMenuSort(Menu menu) {
        menuService.updateSort(menu);
        // 清除用户菜单缓存
        UserUtils.removeCache(UserUtils.CACHE_MENU_LIST);
        UserUtils.removeCache(UserUtils.CACHE_PERMISSION_LIST);
    }

    @Transactional(readOnly = false)
    public void deleteMenu(Menu menu) {
        menuService.delete(menu);
        // 清除用户菜单缓存
        UserUtils.removeCache(UserUtils.CACHE_MENU_LIST);
        UserUtils.removeCache(UserUtils.CACHE_PERMISSION_LIST);
    }


}
